package com.df.hotfix;

import com.df.hotfix.loader.InputFileJavaFileObject;
import com.df.hotfix.loader.MyJavaFileManager;
import com.df.hotfix.scripts.IScript;
import com.df.hotfix.scripts.ScriptHotFixManager;
import com.df.hotfix.scripts.ScriptManager;
import com.df.hotfix.scripts.impl.DemoScript;

import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;

/**
 * 开发阶段热更新（每隔几秒检测一次文件夹下文件变更[脚本变更]，动态编译Java文件）
 * 已上线热更新（Javaagent,classloader,instrument）
 * 远程调试
 * //
 */
public class TestMain {
    public static void main(String[] args) throws Exception {
        ScriptManager.instance().loadScripts();

        ScriptHotFixManager.instance().listenerStart();
        while (true){
            IScript script = ScriptManager.instance().getScript(DemoScript.class.getName());
            script.excute();
            Thread.sleep(3000);
        }

    }

    public static void compileTest() throws IOException {
        String path = "D:\\MyProject\\bakend\\java\\my_test\\hotfix\\src\\main\\java\\com\\df\\hotfix\\scripts\\impl\\DemoScript.java";
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
// 自定义 JavaFileManager 方便自定义输入和输出
        MyJavaFileManager myJavaFileManager = new MyJavaFileManager(compiler.getStandardFileManager(null, null, StandardCharsets.UTF_8));
        JavaCompiler.CompilationTask task = compiler
                .getTask(null, myJavaFileManager, null, null, null,
                        Arrays.asList(new InputFileJavaFileObject(new File(path), "com.df.hotfix.scripts.impl.DemoScript")));
        // 同步调用
        task.call();
        myJavaFileManager.getByteArrayJavaFileObjects().forEach(b1->{
            try {
                ByteArrayOutputStream o= (ByteArrayOutputStream) b1.openOutputStream();
                // 获取字节码
                byte[] classByteArray = o.toByteArray();
                // 加载对象 ，这里是有问题的，我们应该 是在ClassLoader 中编译，并加载
                ClassLoader loader = new ClassLoader() {
                    @Override
                    protected Class<?> findClass(String name) throws ClassNotFoundException {
                        return defineClass(name, classByteArray, 0, classByteArray.length);
                    }
                };
                Class<?> clazz = loader.loadClass("com.df.hotfix.scripts.impl.DemoScript");
                if (IScript.class.isAssignableFrom(clazz)){
                    IScript instance = (IScript) clazz.newInstance();
                    instance.excute();
                }
            } catch (IOException e) {
                e.printStackTrace();
            } catch (ReflectiveOperationException e) {
                e.printStackTrace();
            }
        });
    }
}
